﻿using AutoMapper;
using ERP.Workflow.Designer.Application.Contracts;
using Volo.Abp.AutoMapper;
using ERP.Workflow.Designer.BlazorUI.Models;
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core;
using System.Linq;
using ERP.Workflow.Designer.BlazorUI.Domain;
using ERP.Workflow.Designer.Domain.Shared;

namespace ERP.Workflow.Designer.BlazorUI
{

    public class WorkflowDesignerBlazorUIAutoMapperProfile : Profile
    {
        public WorkflowDesignerBlazorUIAutoMapperProfile()
        {

            CreateMap<Definition, DefinitionDto>().MapExtraProperties(); ;
            CreateMap<FlowNode, NodeDto>()
                 
                  .ForMember(t => t.X, opt => opt.MapFrom(s => s.Position.X))
                  .ForMember(t => t.Y, opt => opt.MapFrom(s => s.Position.Y))
                  .ForMember(t => t.Width, opt => opt.MapFrom(s => s.Size!.Width))
                  .ForMember(t => t.Height, opt => opt.MapFrom(s => s.Size!.Height))
                  .AfterMap((s, t) =>
                   {
                       var ps = typeof(FlowNodeExtendValue).GetProperties();
                       foreach (var p in ps)
                       {
                           var pp = s.GetType().GetProperty(p.Name);
                           t!.ExtraProperties[p.Name] = pp!.GetValue(s, null);
                       }
                   });
            CreateMap<PortAlignment, PortAlignments>().ConvertUsing(s => (PortAlignments)Enum.Parse(typeof(PortAlignments), s.ToString()))  ;
            CreateMap<PortAlignments, PortAlignment>().ConvertUsing(s => (PortAlignment)Enum.Parse(typeof(PortAlignment), s.ToString()));


            CreateMap<PortModel, PortDto>()

                   .ForMember(t => t.PortAlignments, opt => opt.Ignore())
                   .ForMember(t => t.ParentId, opt => opt.Ignore())
                   .ForMember(t => t.Height, opt => opt.MapFrom(s => s.Size.Height))
                   .ForMember(t => t.Width, opt => opt.MapFrom(s => s.Size.Width))
                   .ForMember(t => t.X, opt => opt.MapFrom(s => s.Position.X))
                   .ForMember(t => t.Y, opt => opt.MapFrom(s => s.Position.Y))
                   .AfterMap((s, t) =>
                   {
                       t.PortAlignments = (PortAlignments)Enum.Parse(typeof(PortAlignments), ((int)s.Alignment).ToString());
                       t.ParentId = Guid.Parse(s.Parent.Id);
                   });
                  
            CreateMap<FlowLink, LinkDto>()
                 .ForMember(t => t.Content, opt => opt.MapFrom(s => s.Content ))
                 .ForMember(t => t.SourceNodeId, opt => opt.MapFrom(s => s.SourceNode.Id))
                 .ForMember(t => t.SourcePortId, opt => opt.MapFrom(s => s.SourcePort!.Id))
                 .ForMember(t => t.TargetNodeId, opt => opt.MapFrom(s => s.TargetNode!.Id))
                 .ForMember(t => t.TargetPortId, opt => opt.MapFrom(s => s.TargetPort!.Id))
                 .ForMember(t => t.Paths, opt => opt.MapFrom(s => string.Join(",", s.Paths)))
                  .AfterMap((s, t) =>
                  {
                      var ps = typeof(FlowLinkExtendValue).GetProperties();
                      foreach (var p in ps)
                      {
                          var pp = s.GetType().GetProperty(p.Name);
                          t!.ExtraProperties[p.Name] = pp!.GetValue(s, null);
                      }
                  });
            CreateMap<LinkLabelModel, LinkLabelDto>()
                  .ForMember(t => t.ParentId, opt => opt.MapFrom(s => s.Parent.Id))
                  .ForMember(t => t.Content, opt => opt.MapFrom(s => s.Content))
                  .ForMember(t => t.OffsetX, opt => opt.MapFrom(s => s.Offset!.X))
                  .ForMember(t => t.OffsetY, opt => opt.MapFrom(s => s.Offset!.Y));
                 
            CreateMap<LinkVertexModel, LinkVertexDto>()
                .ForMember(t => t.X, opt => opt.MapFrom(s => s.Position.X))
                .ForMember(t => t.Y, opt => opt.MapFrom(s => s.Position.X));


            CreateMap<DefinitionDto, Definition>().MapExtraProperties();
           
            //
            /*
           
            CreateMap< NodeDto, FlowNode>()
             .ForMember(t => t.Position.X, opt => opt.MapFrom(s => s.X))
             .ForMember(t => t.Position.Y, opt => opt.MapFrom(s => s.Y))
             .AfterMap((s, t) =>
             {
                 var ps = typeof(FlowNodeExtendValue).GetProperties();
                 foreach (var p in ps)
                 {
                     var pp = s.GetType().GetProperty(p.Name);
                     t.GetType()!.GetProperty(p.Name)!.SetValue(t, pp!.GetValue(s, null));
                 }
                 t.Size = new Blazor.Diagrams.Core.Geometry.Size(s.Width, s.Height);
             });

            CreateMap<PortDto, PortModel>()
              .ForMember(t => t.Position.X, opt => opt.MapFrom(s => s.X))
              .ForMember(t => t.Position.Y, opt => opt.MapFrom(s => s.Y))
              .AfterMap((s, t) => {
                  t.Size = new Blazor.Diagrams.Core.Geometry.Size(s.Width, s.Height);
              });
            */
            /*
           CreateMap<LinkDto, FlowLink>()
              .ForMember(t => t.SourceNode.Id, opt => opt.MapFrom(s => s.SourceNodeId))
              .ForMember(t => t.TargetNodeId, opt => opt.MapFrom(s => s.TargetNode!.Id))
              .ForMember(t => t.TargetPortId, opt => opt.MapFrom(s => s.TargetPort!.Id))
              .ForMember(t => t.Paths, opt => opt.MapFrom(s => string.Join(",", s.Paths)))
               .AfterMap((s, t) =>
               {
                 
                   
                   t.SetTargetPort(new PortModel());

                   t.SetSourcePort(new PortModel() );// .SourcePort.Id = s.SourcePortId;
                   var ps = typeof(FlowLinkExtendValue).GetProperties();
                   foreach (var p in ps)
                   {
                       var pp = s.GetType().GetProperty(p.Name);
                       t!.ExtraProperties[p.Name] = pp!.GetValue(s, null);
                   }
               });
            */
            // CreateMap<IdentityRoleDto, IdentityRoleUpdateDto>()
            //   .MapExtraProperties();
        }





    }
     
}
